home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
332_01
/
pressup.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-28
|
18KB
|
834 lines
/*----------------------------------------------------*- Fundamental -*-
Facility: pressup
File: pressup.c
Associated files: - (none)
Description: Strategy board game
Portability: [A Thulin:]
Edited to conform to X/Open Portability
Guide, ed. 3, 1988.
Author: Prof. Steve Ward
Director, Real-Time Systems Group
MIT Lab for Computer Science
Cambridge, Massachussetts, 02139
Editors: Leor Zolman
Anders Thulin
Rydsvagen 288
S-582 50 Linkoping
SWEDEN
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Edit history :
Vers Ed Date By Comments
---- --- ---------- ---------------- -------------------------------
1.0 0 19xx-xx-xx Steve Ward
1.1 1 19xx-xx-xx Leor Zolman
1.2 2 1989-10-25 Anders Thulin Changed to curses-oriented
user interface.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*--- Configuration options:
/* - - Configuration options: - - - - - - - - - - - - - - - - - - - - - - */
/*
* Compile-time environment:
*
* ANSI ANSI C
* BSD BSD Unix, SunOS 3.5
* SV2 AT&T UNIX System V.2
* XPG3 X/Open Portability Guide, ed. 3
* ZTC205 Zortech C 2.05
*
* If you have an ANSI C conforming compiler, you only need to define
* `ANSI'. If you don't, choose one of the other definitions. Don't
* forget to define BEEP() correctly.
*
*/
#define ANSI 0
#define BSD 0
#define SV2 0
#define XPG3 0
#define ZTC205 1
/*
* Run-time environment:
*
* BEEP() See 'comments' below
*
*/
#define BEEP() beep()
/* - - end of configuration options - - - - - - - - - - - - - - - - - - - */
#if ANSI
# include <ctype.h>
# include <curses.h>
# include <stdio.h>
# include <stdlib.h>
extern int getopt(int argc, char **argv, char *optstring);
extern int optind;
extern char *optarg;
#endif
#if BSD
# include <ctype.h>
# include <curses.h>
# include <stdio.h>
extern int getopt();
extern int optind;
extern char *optarg;
extern long strtol();
# define EXIT_FAILURE 1
# define EXIT_SUCCESS 0
#endif
#if SV2
# include <ctype.h>
# include <curses.h>
extern int getopt();
extern int optind;
extern char *optarg;
extern long strtol();
# define EXIT_FAILURE 1
# define EXIT_SUCCESS 0
#endif
#if XPG3
# include <ctype.h>
# include <curses.h>
# include <stdio.h>
# include <stdlib.h>
extern int getopt();
extern int optind;
extern char *optarg;
#endif
#if ZTC205
# include <ctype.h>
# include <curses.h>
# include <stdio.h>
extern int getopt();
extern int optind;
extern char *optarg;
# define EXIT_FAILURE 1
# define EXIT_SUCCESS 0
# define strtol(str, ptr, base) ((base) == 0 ? atoi(str) : (-1))
#endif
/*--- Comments on known problems: -----------------------------------------
curses
Some older implementations of curses may not have the beep()
call. On these systems, you may be able to define BEEP() as
addch(0x07), or perhaps fputc(0x07, stderr) or something
similar.
If you cannot do a beep, try a screen flash
If you cannot do either, just define BEEP to be empty.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
/* 'man-page' based on comments in original program:
pressup(6) pressup(6)
NAME
pressup
SYNOPSIS
pressup [ -f ] [ -d depth ] [ -b ]
DESCRIPTION
The game of Press-Ups is played as follows: The board is a n by
n array of pegs, each of which is standing up at the start of
the game. Pegs come in 3 colors: red (yours), blue (the
machine's), and white (periods, actually; they're neutral.)
The first player to move must `push down' a neutral peg.
Thereafter, players take turns pushing down pegs, where each peg
pushed must be adjacent to the last one pushed.
The player moves the cursor to the wanted peg by using the
`standard' keys h, j, k, and l to move right, down, up and left
respectively. The player then presses the selected key by
pressing the space bar. If an illegal key has been selected,
the program beeps or flashes the screen.
As soon as a player gets all of his pegs down, he wins. When
there are no more legal moves to play, the player with the most
of his own colored pegs down is the winner.
OPTIONS
-f The program makes the first move
-d depth
Set search-depth to 'depth'. Default is 3.
-b Show evaluation of position (negative numbers means
the player has the upper hand, positive that
the program thinks it's winning)
CAVEAT
Watch out...at search depths of 6 or more, this program plays a
mean game!!!
AUTHOR
Steve Ward wrote the original program. Leor Zolman and later
Anders Thulin edited it.
BUGS
(A. Thulin:)
Some players may feel that the keys chosen for cursor movement
(h,j,k and l) are less than intuitive to use. The reason they were
chosen is that many other UNIX-games like hack, nethack,
rogue and vi use these keys for the same purpose. It is left as
an exercise to change it to handle arrow keys with curses.
Complaints to /dev/null.
*/
#define HDR " Pressup 1.2 "
/* Display definitions - depend on 24 x 80 screen: */
#define HDRX 1 /* HDR - Version line */
#define HDRY 1
#define BOARDX 1 /* Upper left corner of board */
#define BOARDY 3
#define STATUSX 1
#define STATUSY 15
#define DEPTHX 30
#define DEPTHY BOARDY
#define SCOREX DEPTHX
#define SCOREY DEPTHY+2
#define HELPX DEPTHX
#define HELPY SCOREY+2
#define STARTX DEPTHX
#define STARTY HELPY+2
#define EVALX DEPTHX
#define EVALY STARTY+2
/* Game definitions: */
#define MAX_SIDE 13 /* Max dimension of board */
#define HISFIRST (Side*2+1) /* His best first move */
#define MYFIRST (Side+Side/2-1) /* My best first move */
#define BACKSP 0x08
int BestMove; /* Returned by search */
char BFlag; /* Debugging flag */
int Depth; /* Search depth (default = 3) */
char FFlag; /* -f option: machine goes first */
int Helpflag;
int Side = 7; /* Current side of board */
char Startflag; /* True on first move only */
char *image;
int Adj[16] = {-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1 };
typedef struct {
char board[MAX_SIDE*MAX_SIDE];
int star;
char red;
char blue;
} BBOARD;
BBOARD initb;
BBOARD master, savebd;
/* Local routines: */
#if __STDC__ != 0
void asknew(void);
void boardcopy(BBOARD *p1, BBOARD *p2);
int CheckWin(BBOARD *bp);
void dmove(int n);
int getmove(void);
int Help(void);
void mmove(BBOARD *bp, int n);
void pboard(BBOARD *bp);
void print_square(BBOARD *bp, int row, int col, int invert);
int search(BBOARD *bp, int ddepth, int who, int alpha, int beta);
#else
void asknew();
void boardcopy();
int CheckWin();
void dmove();
int getmove();
int Help();
void mmove();
void pboard();
void print_square();
int search();
#endif
/*
* Routine: asknew
*
* Description: Ask user if he wants a new game. Quit if not.
*
*/
void asknew()
{
addstr("Another game? ");
refresh();
if (toupper(getchar()) != 'Y') {
move(LINES-1, 0);
refresh();
endwin();
exit(EXIT_SUCCESS);
}
}
/*
* Routine: boardcopy
*
* Description: Copy a board.
*
* Note: Originally copied each element of p1 to p2
* by hand, probably because C didn't allow
* assignments of whole structs. It does now.
*
*/
void boardcopy(p1, p2)
BBOARD *p1, *p2;
{
*p2 = *p1;
}
/*
* Routine: Checkwin
*
* Description: Check if any side has won, and return 1 if so.
* Also print the appropriate text. If no-one has
* won, return 0.
*
*/
int CheckWin(bp)
BBOARD *bp;
{
int i;
i = search(bp, 1, 1, -32000, -32000);
if (BestMove >= 0) return 0;
move(BOARDY+Side+3, STATUSX);
if (i>0) {
addstr("I win! ");
}
if (i<0) {
addstr("You win! ");
}
if (i==0) {
addstr("Tie game! ");
}
return 1;
}
/*
* Rout